package aep

import (
	"errors"
	"strconv"
)

type IBack interface {
	Deal(aep *Aep) error
}

//消息类型枚举
type MsgEnum string

var (
	MsgData  MsgEnum = "dataReport"                //数据变化
	MsgOrder MsgEnum = "commandResponse"           //命令响应
	MsgEvent MsgEnum = "eventReport"               //事件上报
	MsgLine  MsgEnum = "deviceOnlineOfflineReport" //在线离线状态
	MsgTup   MsgEnum = "dataReportTupUnion"        //TUP合并数据变化,未知
)

//==================================================

//固定返回
type ResBack struct {
	TenantID  string      `json:"tenantId"`    //租户id
	ProductID interface{} `json:"productId"`   //产品id
	DeviceID  string      `json:"deviceId"`    //平台设备id
	MsgType   MsgEnum     `json:"messageType"` //消息类型
}

func (this *ResBack) Deal(aep *Aep) error { return nil }

//数据上报
type DataBack struct {
	ResBack
	IMEI         string `json:"imei"`         //imei
	IMSI         string `json:"imsi"`         //imsi
	DeviceType   string `json:"deviceType"`   //设备标示
	Topic        string `json:"topic"`        //上报主题
	AssocAssetID string `json:"assocAssetId"` //合作伙伴id
	Timestamp    int64  `json:"timestamp"`    //时间戳
	UpPacketSN   int    `json:"upPacketSN"`   //上行报文序号
	UpDataSN     int    `json:"upDataSN"`     //数据上报报文序号
	//ServiceID    string    `json:"serviceId"`    //服务id
	Protocol string      `json:"protocol"` //协议类型
	Payload  interface{} `json:"payload"`  //消息载体

}

func (this *DataBack) Deal(aep *Aep) error {
	if aep.FnData != nil {
		return aep.FnData(this)
	}
	return nil
}

//==================================================

type OrderBackCode string

const (
	OrderSUCC      = "SUCCESSFUL" //成功
	OrderSENT      = "SENT"       //已发送
	OrderDeliver   = "DELIVERED"  //已送达
	OrderCompleted = "COMPLETED"  //已完成
	OrderFail      = "FAILED"     //失败
	OrderTimeout   = "TIMEOUT"    //超时
)

//设备命令响应
type OrderBack struct {
	ResBack
	TaskID int `json:"taskId"` //指令任务id
	Result struct {
		ResultCode   OrderBackCode `json:"resultCode"`   //执行状态
		ResultDetail interface{}   `json:"resultDetail"` //执行详情
	} `json:"result"` //执行结果
}

func (this *OrderBack) GetTaskID() string {
	return strconv.Itoa(this.TaskID)
}

func (this *OrderBack) Deal(aep *Aep) error {
	if aep.FnOrder != nil {
		return aep.FnOrder(this)
	}
	return nil
}

func (this *OrderBack) Succ() bool {
	return this.Result.ResultCode == OrderSUCC || this.Result.ResultCode == OrderCompleted
}

func (this *OrderBack) Err() error {
	if this.Result.ResultCode == OrderFail {
		return errors.New("失败")
	} else if this.Result.ResultCode == OrderTimeout {
		return errors.New("超时")
	}
	return nil
}

func (this *OrderBack) Fail() bool {
	return this.Result.ResultCode == OrderFail || this.Result.ResultCode == OrderTimeout
}

//==================================================

//设备事件
type EventBack struct {
	ResBack
	IMEI         string      `json:"imei"`         //imei
	IMSI         string      `json:"imsi"`         //imsi
	DeviceSn     string      `json:"deviceSn"`     //设备编号
	Timestamp    int64       `json:"timestamp"`    //时间戳
	EventType    int         `json:"eventType"`    //事件类型，信息:1,警告:2,故障:3
	EventContent interface{} `json:"eventContent"` //事件数据
	//ServiceID    string      `json:"serviceId"`    //服务id
	Protocol string `json:"protocol"` //协议类型
}

func (this *EventBack) Deal(aep *Aep) error {
	if aep.FnEvent != nil {
		return aep.FnEvent(this)
	}
	return nil
}

//==================================================

//设备上下线
type LineBack struct {
	ResBack
	EventType int   `json:"eventType"` //在线离线,上线：1，下线：0
	Timestamp int64 `json:"timestamp"` //时间戳
}

func (this *LineBack) Deal(aep *Aep) error {
	if aep.FnLine != nil {
		return aep.FnLine(this)
	}
	return nil
}

func (this *LineBack) Online() bool {
	return this.EventType == 1
}

//==================================================

//tup合并数据
type TupBack struct {
	ResBack
}

func (this *TupBack) Deal(aep *Aep) error {
	if aep.FnTup != nil {
		return aep.FnTup(this)
	}
	return nil
}
